package DB;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Random;

import BO.User;


public class UserDB extends User {

	protected UserDB(int userId, String username, int rank, String address, String zipcode,
			String city, String email, String firstname, String surname) {
		super(userId, username, rank, address, zipcode, city, email, firstname, surname);
	}
	
	/**
	 * Get all the available information about a user.
	 * @param username - The username to look for.
	 * @return - User object containing info about the user.
	 */
	public static User getUserByUsername(String username){
		Connection connection = ConnectionPool.getConnection();
		User user = null;
		try {
			Statement stmt = connection.createStatement();
			ResultSet rs = stmt.executeQuery("select * from T_USER where username =\"" + username + "\";");// where username like " + username + ";");
			user = generateUserFromResultSet(rs);
			rs.close();
		} catch (SQLException e){
			throw new RuntimeException(e);
		}
		ConnectionPool.releaseConnection(connection);
		return user;
	}
	
	/**
	 * Try to login. (Verify your username, password combination).
	 * @param username - Username
	 * @param password - Passowrd
	 * @return - Return a user object if correct username/passord otherwise null.
	 */
	public static User login(String username, String password){
		Connection connection = ConnectionPool.getConnection();
		User user = null;
		try {
			Statement stmt = connection.createStatement();
			ResultSet rs = stmt.executeQuery("select salt from T_USER where username =\"" + username + "\";");
			if(rs.next()){
				String salt = rs.getString("salt");
				rs = stmt.executeQuery("select * from T_USER where username = \"" + username + "\" and password = SHA1(\"" + password + salt + "\");");
				user = generateUserFromResultSet(rs);
			}
			rs.close();
		} catch (SQLException e){}
		ConnectionPool.releaseConnection(connection);
		return user;
	}
	
	/**
	 * Try to create a user, will only work if username is unique.
	 * @param username - Username.
	 * @param password - Passord.
	 * @param rank - Permission rank.
	 * @param address - User address.
	 * @param zipcode - ZipCode.
	 * @param city - City.
	 * @param email - Email.
	 * @param firstname - Users first name.
	 * @param surname - Users surname.
	 * @return True or false, if user was created.
	 */
	public static boolean createUser(String username, String password, int rank, String address, String zipcode, String city, String email, String firstname, String surname){
		Connection connection = ConnectionPool.getConnection();
		boolean inserted = false;;
		try {
			Statement stmt = connection.createStatement();
			String salt = getSalt(20);
			int nr = stmt.executeUpdate("insert into T_USER (username,password,salt,rank,address,zipcode,city,email,firstname,surname) values (\"" +
					username + "\",SHA1(\"" + password + salt + "\"),\"" + salt + "\"," + rank + ",\"" + address + "\",\"" + zipcode + "\",\"" + city + "\",\"" + email + "\",\"" + firstname + "\",\"" + surname + "\");");
			inserted = nr == 1;
			stmt.close();
		} catch (SQLException e){}
		ConnectionPool.releaseConnection(connection);
		return inserted;
	}
	
	/**
	 * Edit the information about a user.
	 * @param id - The user id that will be edited.
	 * @param username - New username.
	 * @param rank - New Rank.
	 * @param address - New Address.
	 * @param zipcode - New ZipCode.
	 * @param city - New City.
	 * @param email - New Email.
	 * @param firstname - New First name.
	 * @param surname - New Surname.
	 */
	public static void editUser(int id, String username, int rank, String address, String zipcode, String city, String email, String firstname, String surname){
		Connection connection = ConnectionPool.getConnection();
		try {
			Statement stmt = connection.createStatement();
			stmt.executeUpdate("update T_USER set username = \"" + username + "\", rank = " + rank + ", address = \"" + address + "\", " +
					"zipcode = \"" + zipcode + "\", city = \"" + city + "\", email = \"" + email + "\", firstname = \"" + firstname + "\", surname = \"" + surname + "\" where user_id = " + id + ";");
			stmt.close();
		} catch (SQLException e){
			e.printStackTrace();
		}
		ConnectionPool.releaseConnection(connection);
	}
	
	/*
	 * Help method to create the salt for the user. 
	 * @param length - Length of the requested salt.
	 * @return - Return a salt containing 0-9 a-z A-Z
	 */
	private static String getSalt(int length){
		Random rand = new Random();
		String salt = "";
		while(salt.length() != length){
			int r = rand.nextInt(125);
			if(r >= 48 && r <= 57){//0-9
				char c = (char) r;
				salt += c;
			}else if(r >= 65 && r <= 90){//A-Z
				char c = (char) r;
				salt += c;
			}else if(r >= 97 && r <= 122){//a-z
				char c = (char) r;
				salt += c;
			}
		}
		return salt;
	}
	
	/*
	 * Help method to generate User data from a ResultSet.
	 * @param rs - ResultSet to use.
	 * @return - Return a User object.
	 */
	private static User generateUserFromResultSet(ResultSet rs){
		try{
			if(rs.next()){
				int userId = rs.getInt("user_id");
				String username = rs.getString("username");
				int rank = rs.getInt("rank");
				String address = rs.getString("address");
				String zipcode = rs.getString("zipcode");
				String city = rs.getString("city");
				String firstname = rs.getString("firstname");
				String surname = rs.getString("surname");
				String email = rs.getString("email");
				return new UserDB(userId,username,rank,address,zipcode,city,firstname,surname,email);
			}
		} catch (SQLException e){
			throw new RuntimeException(e);
		}
		return null;
	}

}
